/* 
 * Parser in Bison
 *
 */

%{
    /* C declarations */
    
    int yyerror (char *s);
    int yylex();
%}

%token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
%token INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN

%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID

%token IF ELSE WHILE GOTO CONTINUE BREAK RETURN

%start main

%%
//-------------------------------------------------------------------------

assignment_expression
	: postfix_expression
	| postfix_expression '=' assignment_expression
	;

primary_expression
	: IDENTIFIER
	| CONSTANT
	| STRING_LITERAL
	| '(' expression ')'
	;

postfix_expression
	: primary_expression
	| postfix_expression '(' ')'
	;
	
expression
	: assignment_expression
	| expression ',' assignment_expression
	;

type_qualifier
	: CONST
	| VOLATILE
	;

declaration
	: declaration_specifiers ';'
	| declaration_specifiers init_declarator_list ';'
	;

declaration_specifiers
	: type_specifier
	| type_specifier declaration_specifiers
	| type_qualifier
	| type_qualifier declaration_specifiers
	;

init_declarator_list
	: init_declarator
	| init_declarator_list ',' init_declarator
	;

init_declarator
	: declarator
	| declarator '=' assignment_expression
	;

type_specifier
	: VOID
	| CHAR
	| SHORT
	| INT
	| LONG
	| FLOAT
	| DOUBLE
	| SIGNED
	| UNSIGNED
	;

declarator
	: IDENTIFIER
	| declarator '(' ')'
	;

statement
	: compound_statement
	| expression_statement
	| jump_statement
	;

compound_statement
	: '{' '}'
	| '{' statement_list '}'
	| '{' declaration_list '}'
	| '{' declaration_list statement_list '}'
	;

declaration_list
	: declaration
	| declaration_list declaration
	;

statement_list
	: statement
	| statement_list statement
	;

expression_statement
	: ';'
	| expression ';'
	;

jump_statement
	: RETURN ';'
	| RETURN expression ';'
	;

main
	: declaration_specifiers declarator compound_statement
	;
	
%%
//-------------------------------------------------------------------------
//-- addional c-code

#include "flexer.c"

int yyerror (char *s)
{
  printf ("Syntax Error: %s\n", s);
  
  return 1;
}

int main(int agrc, char **argv)
{
	yyparse();
	return 0;
}